﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Runtime.Serialization;
using Mono.Cecil;

namespace Cubicle.Core.DataContracts
{
    [DataContract]
    [Serializable]
    public class TypeData
    {
        [DataMember]
        public string FullName { get; set; }
        [DataMember]
        public bool IsClass { get; set; }
        [DataMember]
        public bool IsValueType { get; set; }
        [DataMember]
        public bool IsEnum { get; set; }
        [DataMember]
        public bool IsInterface { get; set; }
        [DataMember]
        public bool IsArray { get; set; }
        [DataMember]
        public bool IsPointer { get; set; }
        [DataMember]
        public bool IsAbstract { get; set; }
        [DataMember]
        public bool IsGenericType { get; set; }
        [DataMember]
        public bool IsPrimitive { get; set; }
        [DataMember]
        public bool IsPublic { get; set; }
        [DataMember]
        public bool IsSealed { get; set; }
        [DataMember]
        public bool IsSerializable { get; set; }
        [DataMember]
        public string FullyQualifiedName { get; set; }
        [DataMember]
        public IEnumerable<string> InterfaceNames { get; set; }
        [DataMember]
        public string Path { get; set; }

        public TypeData(Type t)
        {
            FullName = t.FullName;
            IsClass = t.IsClass;
            IsValueType = t.IsValueType;
            IsEnum = t.IsEnum;
            IsInterface = t.IsInterface;
            IsArray = t.IsArray;
            IsPointer = t.IsPointer;
            IsAbstract = t.IsAbstract;
            IsGenericType = t.IsGenericType;
            IsPrimitive = t.IsPrimitive;
            IsPublic = t.IsPublic;
            IsSealed = t.IsSealed;
            IsSerializable = t.IsSerializable;
            FullyQualifiedName = t.Module.FullyQualifiedName;
            InterfaceNames = t.GetInterfaces().Select(x => x.FullName).ToList();
            Path = t.DeclaringType != null 
                ? t.DeclaringType.Assembly.CodeBase
                : null;
        }

        public TypeData(TypeDefinition t, string path)
        {
            FullName = t.FullName;
            IsClass = t.IsClass;
            IsClass = t.IsClass;
            IsValueType = t.IsValueType;
            IsEnum = t.IsEnum;
            IsInterface = t.IsInterface;
            IsArray = t.IsArray;
            IsPointer = t.IsPointer;
            IsAbstract = t.IsAbstract;
            IsGenericType = t.HasGenericParameters;
            IsPrimitive = t.IsPrimitive;
            IsPublic = t.IsPublic;
            IsSealed = t.IsSealed;
            IsSerializable = t.IsSerializable;
            FullyQualifiedName = t.Module.FullyQualifiedName;
            InterfaceNames = t.Interfaces.Select(x => x.FullName).ToList();
            Path = path;
        }
    }
}